
import logging

from rest_framework.permissions import IsAuthenticated
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, viewsets
from django.shortcuts import get_object_or_404

from tools.nutrition_qiniu import qn
from .models import MealPlan, NutritionAnalysis
from .serializers import MealPlanSerializer, UserProfileSerializer, NutritionAnalysisSerializer
from .services import DietPlanService
from user.models import UserProfile, User


from .utils.mtools import recognize_nutrition_text, get_nutrition_advice


logger = logging.getLogger('django')


def get_user_from_request(request):
    """从请求中获取用户信息，处理认证异常"""
    try:
        user_id = request.user_info.get('user_id')
        if not user_id:
            return None, Response({
                'error': '用户信息获取失败，请重新登录'
            }, status=status.HTTP_401_UNAUTHORIZED)
    except AttributeError:
        return None, Response({
            'error': '用户未认证，请先登录'
        }, status=status.HTTP_401_UNAUTHORIZED)
    
    try:
        user = get_object_or_404(User, id=user_id)
        user_profile = get_object_or_404(UserProfile, user=user)
        return (user, user_profile), None
    except Exception as e:
        logger.error(f"获取用户信息失败: {e}")
        return None, Response({
            'error': '用户信息获取失败'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@method_decorator(csrf_exempt, name='dispatch')
class GenerateDietPlanView(APIView):
    """生成饮食计划API视图"""

    def post(self, request):
        # 从中间件获取用户信息
        user, response = get_user_from_request(request)
        if response:
            return response

        # 使用饮食计划服务生成计划
        service = DietPlanService()
        meal_plan = service.generate_meal_plan(user[1], int(request.data.get('days', 7)))

        # 序列化并返回结果
        serializer = MealPlanSerializer(meal_plan)
        return Response(serializer.data, status=status.HTTP_201_CREATED)


@method_decorator(csrf_exempt, name='dispatch')
class UserMealPlansView(APIView):
    """获取用户饮食计划列表API视图"""

    def get(self, request):
        user, response = get_user_from_request(request)
        if response:
            return response

        user_profile = user[1]
        meal_plans = MealPlan.objects.filter(user=user_profile).order_by('-created_at')

        serializer = MealPlanSerializer(meal_plans, many=True)
        return Response(serializer.data)


@method_decorator(csrf_exempt, name='dispatch')
class UserProfileView(APIView):
    """用户档案API视图"""

    def get(self, request):
        """获取用户档案信息"""
        user, response = get_user_from_request(request)
        if response:
            return response

        user_profile = user[1]
        serializer = UserProfileSerializer(user_profile)
        return Response(serializer.data)

    def put(self, request):
        """更新用户档案信息"""
        user, response = get_user_from_request(request)
        if response:
            return response

        user_profile = user[1]
        serializer = UserProfileSerializer(user_profile, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@method_decorator(csrf_exempt, name='dispatch')
class MealPlanDetailView(APIView):
    """饮食计划详情API视图"""

    def get(self, request, plan_id):
        """获取饮食计划详情"""
        user, response = get_user_from_request(request)
        if response:
            return response

        user_profile = user[1]
        meal_plan = get_object_or_404(MealPlan, id=plan_id, user=user_profile)
        serializer = MealPlanSerializer(meal_plan)
        return Response(serializer.data)


@method_decorator(csrf_exempt, name='dispatch')
class NutritionAnalysisView(APIView):
    """营养分析API，使用用户已有的身体指标信息"""

    def post(self, request):
        # 获取数据
        image_url = request.data.get('image_url')
        net_weight = request.data.get('net_weight')

        # 验证必要参数
        if not all([image_url, net_weight]):
            return Response({
                'error': '缺少必要参数: image_url, net_weight'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 检查用户是否有完整的身体指标信息
        user, response = get_user_from_request(request)
        if response:
            return response

        user_profile = user[1]
        if not all([user_profile.height, user_profile.weight, user_profile.birth_date]):
            return Response({
                'error': '请先完善您的身体指标信息'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 识别营养成分
            nutrition_text, error = recognize_nutrition_text(image_url)
            if error:
                return Response({
                    'error': f'OCR识别失败: {error}'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取营养建议，使用用户的详细身体指标信息
            logger.info(f"开始获取营养建议，营养成分文本: {nutrition_text[:100]}...")
            advice, error = get_nutrition_advice(nutrition_text, user_profile, net_weight)
            if error:
                logger.error(f"营养分析失败: {error}")
                return Response({
                    'error': f'营养分析失败: {error}'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
            logger.info(f"营养建议获取成功: {advice[:100]}...")

            # 保存分析结果到数据库
            analysis = NutritionAnalysis(
                user=user[0],
                net_weight=float(net_weight),
                image=image_url,  # 存储七牛云图片URL
                nutrition_text=nutrition_text,
                advice=advice
            )
            analysis.save()

            # 返回结果
            serializer = NutritionAnalysisSerializer(analysis)
            return Response(serializer.data)

        except Exception as e:
            return Response({
                'error': f'服务器内部错误: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@method_decorator(csrf_exempt, name='dispatch')
class GetUserProfileView(APIView):
    """获取用户身体指标信息"""

    def get(self, request):
        user, response = get_user_from_request(request)
        if response:
            return response

        user_profile = user[1]
        serializer = UserProfileSerializer(user_profile)
        return Response(serializer.data)


@method_decorator(csrf_exempt, name='dispatch')
class GetQiNiuToken(APIView):
    """
    获取七牛云上传凭证
    """
    def get(self, request):
        token = qn.qiniu_token()
        logger.info(f"七牛云token: {token}")
        return Response({'token': token})